#ifndef __WM_LCD_H__
#define __WM_LCD_H__

#include "wm_hal.h"

#define LCD		(LCD_TypeDef *)LCD_BASE

typedef struct
{
	uint32_t HighDrive;				/* Configures the LCD High Drive. This parameter can be 
									* 	a value of @LCD_HighDrive */
	uint32_t Bias;					/* Configures the LCD bias. This parameter can be a value of @LCD_BIAS */
	uint32_t Volt;					/* Specifies the output voltage. This parameter can be a value of @LCD_VOLTAGE */
	uint32_t Duty;					/* Configures the LCD duty. This parameter can be a value of @LCD_DUTY */
	uint32_t Freq;					/* Specifies the freq. */
	uint32_t ComEn;				/* Specifies the com used. bit0~7 corresponds to com0~7, set 1 to use, set 0 to not use. */
	uint32_t SegEn;					/* Specifies the seg used. bit0~31 corresponds to seg0~31, set 1 to use, set 0 to not use. */
} LCD_InitTypeDef;

typedef enum
{
	HAL_LCD_STATE_RESET,			/* LCD not initialized or disabled */
	HAL_LCD_STATE_READY,			/* LCD initialized and ready for use */
	HAL_LCD_STATE_BUSY,				/* LCD process ongoing */
}HAL_LCD_StateTypeDef;

typedef struct
{
	LCD_TypeDef 		*Instance;	/* LCD registers base address */
	
	LCD_InitTypeDef		Init;		/* LCD required parameters */
	
	HAL_LockTypeDef		Lock;		/* Locking object */
	
	__IOM HAL_LCD_StateTypeDef	State;	/* LCD State */
	
} LCD_HandleTypeDef;

// LCD_HighDrive
#define LCD_HIGHDRIVE_0		((uint32_t)0x00000000U)
#define LCD_HIGHDRIVE_1		LCD_CR_DRVSTRENGTH

// LCD_BIAS
#define LCD_BIAS_STATIC		LCD_CR_BIAS_STATIC	// static bias
#define LCD_BIAS_1_2		LCD_CR_BIAS_1_2		// 1/2 bias
#define LCD_BIAS_1_3		LCD_CR_BIAS_1_3		// 1/3 bias
#define LCD_BIAS_1_4		LCD_CR_BIAS_1_4		// 1/4 bias

// LCD_VOLTAGE
#define LCD_VOLT_2_7		LCD_CR_VOL_2_7		// 2.7v
#define LCD_VOLT_2_9		LCD_CR_VOL_2_9		// 2.9v
#define LCD_VOLT_3_1		LCD_CR_VOL_3_1		// 3.1v
#define LCD_VOLT_3_3		LCD_CR_VOL_3_3		// 3.3v

// LCD_DUTY
#define LCD_DUTY_1_STATIC	LCD_CR_DUTY_STATIC	// static
#define LCD_DUTY_1_2		LCD_CR_DUTY_1_2		// 1/2 duty
#define LCD_DUTY_1_3		LCD_CR_DUTY_1_3		// 1/3 duty
#define LCD_DUTY_1_4		LCD_CR_DUTY_1_4		// 1/4 duty
#define LCD_DUTY_1_5		LCD_CR_DUTY_1_5		// 1/5 duty
#define LCD_DUTY_1_6		LCD_CR_DUTY_1_6		// 1/6 duty
#define LCD_DUTY_1_7		LCD_CR_DUTY_1_7		// 1/7 duty
#define LCD_DUTY_1_8		LCD_CR_DUTY_1_8		// 1/8 duty


#define IS_LCD_ALL_INSTANCE(__INSTANCE__)	((__INSTANCE__) == LCD)
#define IS_LCD_RAM_REGISTER_INDEX(INDEX)	(((INDEX) >= 0) && ((INDEX) <= 7))

#define IS_LCD_HIGHDRIVE(HIGHDRIVE)				(((HIGHDRIVE) == LCD_HIGHDRIVE_0) || ((HIGHDRIVE) == LCD_HIGHDRIVE_1))

#define IS_LCD_BIAS(BIAS)					(((BIAS) == LCD_BIAS_STATIC) || ((BIAS) == LCD_BIAS_1_2) || \
											 ((BIAS) == LCD_BIAS_1_3) || ((BIAS) == LCD_BIAS_1_4))
											 
#define IS_LCD_VOLTAGE(VOLT)				(((VOLT) == LCD_VOLT_2_7) || ((VOLT) == LCD_VOLT_2_9) || \
											 ((VOLT) == LCD_VOLT_3_1) || ((VOLT) == LCD_VOLT_3_3))
											 
#define IS_LCD_DUTY(DUTY)					(((DUTY) == LCD_DUTY_STATIC) || ((DUTY) == LCD_DUTY_1_2) || \
											 ((DUTY) == LCD_DUTY_1_3) || ((DUTY) == LCD_DUTY_1_4) || \
											 ((DUTY) == LCD_DUTY_1_5) || ((DUTY) == LCD_DUTY_1_6) || \
											 ((DUTY) == LCD_DUTY_1_7) || ((DUTY) == LCD_DUTY_1_8))

#define __HAL_LCD_ENABLE(__HANDLE__)		(SET_BIT((__HANDLE__)->Instance->CR, LCD_CR_EN))
#define __HAL_LCD_DISABLE(__HANDLE__)		(CLEAR_BIT((__HANDLE__)->Instance->CR, LCD_CR_EN))

HAL_StatusTypeDef HAL_LCD_Init(LCD_HandleTypeDef *hlcd);
HAL_StatusTypeDef HAL_LCD_DeInit(LCD_HandleTypeDef *hlcd);
void HAL_LCD_MspInit(LCD_HandleTypeDef *hlcd);
void HAL_LCD_MspDeInit(LCD_HandleTypeDef *hlcd);
HAL_StatusTypeDef HAL_LCD_Write(LCD_HandleTypeDef *hlcd, uint32_t RAMRegisterIndex, uint32_t RAMRegisterMask, uint32_t Data);
HAL_StatusTypeDef HAL_LCD_Clear(LCD_HandleTypeDef *hlcd);

#endif